package org.jetnuke.dao.generic;

import org.apache.log4j.Logger;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import net.jforum.JForumExecutionContext;
import net.jforum.dao.generic.AutoKeys;
import net.jforum.util.preferences.SystemGlobals;

import org.jetnuke.dao.CalendarEventDAO;
import org.jetnuke.entities.CalendarEvent;

public class GenericCalendarEventDAO extends AutoKeys implements
		CalendarEventDAO {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(GenericCalendarEventDAO.class);

	public int addNew(CalendarEvent ce) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("addNew(CalendarEvent) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = this
				.getStatementForAutoKeys("CalendarEventModel.addNew");
		this.setAutoGeneratedKeysQuery(SystemGlobals
				.getSql("CalendarEventModel.lastGeneratedCalendarEventID"));
		initNewCalendarEvent(ce, p);

		int id = this.executeAutoKeysQuery(p);
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("addNew(CalendarEvent) - end"); //$NON-NLS-1$
		}
		return id;
	}

	private void initNewCalendarEvent(CalendarEvent ce, PreparedStatement p)
			throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("initNewCalendarEvent(CalendarEvent, PreparedStatement) - start"); //$NON-NLS-1$
		}

		p.setInt(1, ce.getUID());
		p.setString(2, ce.getTITLE());
		p.setString(3, ce.getFULLDESC());
		p.setInt(4, ce.getTYPE());
		p.setDate(5, new java.sql.Date(ce.getSTART_DATE().getTime()));
		if (ce.getSTART_TIME() != null) {
			p.setTime(6, new Time(ce.getSTART_TIME().getTime()));
			p.setTime(7, new Time(ce.getDURATION().getTime()));
		} else {
			p.setTime(6, null);
			p.setTime(7, null);
		}

		p.setString(8, ce.getLOCATION());
		p.setInt(9, ce.getRECURRING());
		p.setInt(10, ce.getFREQ());
		p.setInt(11, ce.getWF());
		p.setInt(12, ce.getWD());
		p.setInt(13, ce.getWX());
		if (ce.getEXPIRATION() != null)
			p.setDate(14, new java.sql.Date(ce.getEXPIRATION().getTime()));
		else
			p.setDate(14, null);

		if (logger.isDebugEnabled()) {
			logger
					.debug("initNewCalendarEvent(CalendarEvent, PreparedStatement) - end"); //$NON-NLS-1$
		}
	}

	public List selectAllByUID(int uid) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("selectAllByUID(int) - start"); //$NON-NLS-1$
		}

		// TODO Auto-generated method stub

		if (logger.isDebugEnabled()) {
			logger.debug("selectAllByUID(int) - end"); //$NON-NLS-1$
		}
		return null;
	}

	public List selectUpcomingByUID(int uid) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("selectUpcomingByUID(int) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext
				.getConnection()
				.prepareStatement(
						SystemGlobals
								.getSql("CalendarEventModel.selectUpcomingByUID"));
		p.setInt(1, uid);
		ResultSet rs = p.executeQuery();
		List list = this.processSelectAll(rs);
		rs.close();
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("selectUpcomingByUID(int) - end"); //$NON-NLS-1$
		}
		return list;
	}

	protected List processSelectAll(ResultSet rs) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("processSelectAll(ResultSet) - start"); //$NON-NLS-1$
		}

		List list = new ArrayList();
		while (rs.next()) {
			CalendarEvent u = new CalendarEvent();
			fillCalendarEventFromResultSet(u, rs);
			list.add(u);
		}

		if (logger.isDebugEnabled()) {
			logger.debug("processSelectAll(ResultSet) - end"); //$NON-NLS-1$
		}
		return list;
	}

	protected void fillCalendarEventFromResultSet(CalendarEvent u, ResultSet rs)
			throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("fillCalendarEventFromResultSet(CalendarEvent, ResultSet) - start"); //$NON-NLS-1$
		}

		u.setDURATION(rs.getTime("DURATION"));
		u.setEXPIRATION(rs.getDate("EXPIRATION"));
		u.setFREQ(rs.getInt("FREQ"));
		u.setFULLDESC(rs.getString("FULLDESC"));
		u.setID(rs.getInt("ID"));
		u.setLOCATION(rs.getString("LOCATION"));
		u.setRECURRING(rs.getInt("RECURRING"));
		u.setSTART_DATE(rs.getDate("START_DATE"));
		u.setSTART_TIME(rs.getTime("START_TIME"));
		u.setTITLE(rs.getString("TITLE"));
		u.setTYPE(rs.getInt("TYPE"));
		u.setUID(rs.getInt("UID"));
		u.setWD(rs.getInt("WD"));
		u.setWF(rs.getInt("WF"));
		u.setWX(rs.getInt("WX"));

		if (logger.isDebugEnabled()) {
			logger
					.debug("fillCalendarEventFromResultSet(CalendarEvent, ResultSet) - end"); //$NON-NLS-1$
		}
	}

	public List selectPastByUID(int uid) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("selectPastByUID(int) - start"); //$NON-NLS-1$
		}

		// TODO Auto-generated method stub

		if (logger.isDebugEnabled()) {
			logger.debug("selectPastByUID(int) - end"); //$NON-NLS-1$
		}
		return null;
	}

	public CalendarEvent selectByPK(int id) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("selectByPK(int) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext.getConnection()
				.prepareStatement(
						SystemGlobals.getSql("CalendarEventModel.selectByID"));
		p.setInt(1, id);

		ResultSet rs = p.executeQuery();
		CalendarEvent ce = new CalendarEvent();

		if (rs.next()) {
			fillCalendarEventFromResultSet(ce, rs);
		}

		rs.close();
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("selectByPK(int) - end"); //$NON-NLS-1$
		}
		return ce;
	}

	public List selectDayEvents(int uid, GregorianCalendar gc) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("selectDayEvents(int, GregorianCalendar) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext.getConnection()
				.prepareStatement(
						SystemGlobals
								.getSql("CalendarEventModel.selectDayEvents"));
		p.setInt(1, uid);
		p.setDate(2, new java.sql.Date(gc.getTimeInMillis()));
		ResultSet rs = p.executeQuery();
		List list = this.processSelectAll(rs);
		rs.close();
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("selectDayEvents(int, GregorianCalendar) - end"); //$NON-NLS-1$
		}
		return list;
	}

	public List selectRecurringEvents(int uid, GregorianCalendar gc)
			throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("selectRecurringEvents(int, GregorianCalendar) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext
				.getConnection()
				.prepareStatement(
						SystemGlobals
								.getSql("CalendarEventModel.selectRecurringEvents"));
		p.setInt(1, uid);
		Date dt = new java.sql.Date(gc.getTimeInMillis());
		p.setDate(2, dt);
		p.setDate(3, dt);
		ResultSet rs = p.executeQuery();
		List list = this.processSelectAll(rs);
		rs.close();
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("selectRecurringEvents(int, GregorianCalendar) - end"); //$NON-NLS-1$
		}
		return list;
	}

	public List selectPeriodRecurringEvents(int id, GregorianCalendar firstDay,
			GregorianCalendar lastDay) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("selectPeriodRecurringEvents(int, GregorianCalendar, GregorianCalendar) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext
				.getConnection()
				.prepareStatement(
						SystemGlobals
								.getSql("CalendarEventModel.selectPeriodRecurringEvents"));
		p.setInt(1, id);
		Date dtFirst = new java.sql.Date(firstDay.getTimeInMillis());
		Date dtLast = new java.sql.Date(lastDay.getTimeInMillis());
		p.setDate(2, dtLast);
		p.setDate(3, dtFirst);
		ResultSet rs = p.executeQuery();
		List list = this.processSelectAll(rs);
		rs.close();
		p.close();

		if (logger.isDebugEnabled()) {
			logger
					.debug("selectPeriodRecurringEvents(int, GregorianCalendar, GregorianCalendar) - end"); //$NON-NLS-1$
		}
		return list;
	}

	public List selectDaysWithEvents(int uid, int year) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("selectDaysWithEvents(int, int) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext
				.getConnection()
				.prepareStatement(
						SystemGlobals
								.getSql("CalendarEventModel.selectDaysWithEvents"));
		p.setInt(1, uid);
		GregorianCalendar first = new GregorianCalendar(year, 0, 1, 0, 0);
		first.set(Calendar.SECOND, 0);
		first.set(Calendar.MILLISECOND, 0);
		long firstTime = first.getTimeInMillis();
		GregorianCalendar last = new GregorianCalendar(year + 1, 0, 1, 0, 0);
		last.set(Calendar.SECOND, 0);
		last.set(Calendar.MILLISECOND, 0);
		p.setDate(2, new java.sql.Date(firstTime));
		p.setDate(3, new java.sql.Date(last.getTimeInMillis()));
		ResultSet rs = p.executeQuery();
		List list = new ArrayList();
		while (rs.next()) {
			Date dt = rs.getDate(1);
			GregorianCalendar tmp = new GregorianCalendar();
			tmp.setTime(dt);
			list.add(tmp);
		}
		rs.close();
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("selectDaysWithEvents(int, int) - end"); //$NON-NLS-1$
		}
		return list;
	}

	public void update(CalendarEvent ce) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("update(CalendarEvent) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext.getConnection()
				.prepareStatement(
						SystemGlobals.getSql("CalendarEventModel.update"));
		p.setString(1, ce.getTITLE());
		p.setString(2, ce.getFULLDESC());
		p.setInt(3, ce.getTYPE());
		p.setDate(4, new java.sql.Date(ce.getSTART_DATE().getTime()));
		if (ce.getSTART_TIME() != null) {
			p.setTime(5, new Time(ce.getSTART_TIME().getTime()));
			p.setTime(6, new Time(ce.getDURATION().getTime()));
		} else {
			p.setTime(5, null);
			p.setTime(6, null);
		}

		p.setString(7, ce.getLOCATION());
		p.setInt(8, ce.getRECURRING());
		p.setInt(9, ce.getFREQ());
		p.setInt(10, ce.getWF());
		p.setInt(11, ce.getWD());
		p.setInt(12, ce.getWX());
		if (ce.getEXPIRATION() != null)
			p.setDate(13, new java.sql.Date(ce.getEXPIRATION().getTime()));
		else
			p.setDate(13, null);
		p.setInt(14, ce.getID());
		p.executeUpdate();
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("update(CalendarEvent) - end"); //$NON-NLS-1$
		}
	}

	public void deleteByPk(int id) throws Exception {
		if (logger.isDebugEnabled()) {
			logger.debug("deleteByPk(int) - start"); //$NON-NLS-1$
		}

		PreparedStatement p = JForumExecutionContext.getConnection()
				.prepareStatement(
						SystemGlobals.getSql("CalendarEventModel.deleteByPk"));
		p.setInt(1, id);
		p.executeUpdate();
		p.close();

		if (logger.isDebugEnabled()) {
			logger.debug("deleteByPk(int) - end"); //$NON-NLS-1$
		}
	};

}
